package com.petRescueCenter.demo.posting.controller;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import javax.servlet.http.HttpSession;

import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.petRescueCenter.demo.common.enumPackage.LockedEmun;
import com.petRescueCenter.demo.common.util.ProjectPath;
import com.petRescueCenter.demo.common.web.VueResponse;
import com.petRescueCenter.demo.common.web.VuejsPageRequest;
import com.petRescueCenter.demo.img.entity.Img;
import com.petRescueCenter.demo.img.service.IImgService;
import com.petRescueCenter.demo.posting.entity.Posting;
import com.petRescueCenter.demo.posting.entity.dto.PostingDTO;
import com.petRescueCenter.demo.posting.entity.dto.PostingQueryDTO;
import com.petRescueCenter.demo.posting.lucene.Search;
import com.petRescueCenter.demo.posting.lucene.index;
import com.petRescueCenter.demo.posting.service.IPostingService;
import com.petRescueCenter.demo.user.entity.User;
import com.petRescueCenter.demo.user.service.IUserService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;

@Api(description = "帖子相关的api")
@RestController
@RequestMapping("/posting")
public class PostingController {
	@Autowired
	private IPostingService postingService;
	@Autowired
	private IUserService userService;
	@Autowired
	private IImgService imgService;

	@ApiOperation(value = "查询帖子信息", notes = "分页返回")
	@GetMapping
	public Page<PostingDTO> getAll(PostingQueryDTO postingQueryDTO, VuejsPageRequest pageRequest) {
		return postingService.findAll(postingQueryDTO.getFansId(), PostingQueryDTO.getWhereClause(postingQueryDTO),
				pageRequest.getPageable());

	}

	// @Scheduled(fixedRate = 3000)
	public void index() throws Exception {

		List<PostingDTO> postings = postingService.findAll();
		new index().indexer(postings);

	}

	@GetMapping("/search")
	public Page<PostingDTO> search(String search, PostingQueryDTO postingQueryDTO, VuejsPageRequest pageRequest)
			throws IOException, ParseException, InvalidTokenOffsetsException {
		List<PostingDTO> postings = new Search().query(search);
		Long[] ids = new Long[postings.size()];
		int i = 0;
		for (PostingDTO p : postings) {
			ids[i] = p.getId();
			i++;
		}
		postingQueryDTO.setIds(ids);
		return postingService.findAll(postingQueryDTO.getFansId(), postings,
				PostingQueryDTO.getWhereClause(postingQueryDTO), pageRequest);
	}

	@PostMapping("/addImg")
	public VueResponse addImg(@RequestParam("file") MultipartFile file) {
		try {
			String fileType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
			System.err.println("111111");
			// p1为路径，user.getName()为相片名字，fileType为类型

			String filename = UUID.randomUUID() + fileType;
			Path path = Paths.get(ProjectPath.getRootPath("static/img/posting/") + filename);
			File filePath = new File(ProjectPath.getRootPath("static/img/posting/"));
			System.out.println(filePath);
			System.out.println("文件的保存路径：" + path);
			if (!filePath.exists() && !filePath.isDirectory()) {
				System.out.println("目录不存在，创建目录:" + filePath);
				filePath.mkdir();
			}
			Img img = new Img();
			img.setImg("img/posting/" + filename);
			// 把获得的文件保存
			file.transferTo(path.toFile());
			img = imgService.save(img);
			return new VueResponse(true, img.getId().toString());
		} catch (Exception e) {
			// TODO: handle exception
			return new VueResponse(false, "发表失败！");
		}
	}

	@PostMapping("/deleteMore")
	public VueResponse deleteMore(@RequestParam("ids") Long[] ids) {
		try {
			for (Long id : ids) {
				postingService.deleteById(id);
			}
			return new VueResponse(true, "删除成功！");
		} catch (Exception e) {
			// TODO: handle exception
			return new VueResponse(false, "操作失败！！");

		}
	}

	@PostMapping("/deleteImg")
	public VueResponse deleteImg(@RequestParam("id") Long id) {
		try {
			Img img = new Img();
			img = imgService.findById(id);
			File oldFile = new File(ProjectPath.getRootPath("static/") + img.getImg());
			if (oldFile.exists())
				oldFile.delete();
			imgService.deleteById(id);
			return new VueResponse(true, "删除成功");
		} catch (Exception e) { // TODO: handle exception
			return new VueResponse(false, "删除失败！");
		}
	}

	@PostMapping("/approvePosting")
	public VueResponse approvePosting(@RequestParam("id") Long id) {
		try {
			Posting p = postingService.findById(id);
			p.setState(LockedEmun.YES);
			postingService.save(p);
			return new VueResponse(true, "发布成功");
		} catch (Exception e) { // TODO: handle exception
			return new VueResponse(false, "发布失败！");
		}
	}

	@ApiOperation(value = "添加帖子", notes = "不同的模块添加的帖子的类型不一样，用户帖子0,失宠招领1,寻宠启示2,注意事项3")
	@ApiImplicitParam(name = "file", value = "文件", required = false, dataType = "MultipartFile[]")
	@PostMapping
	public VueResponse create(PostingDTO postingDTO, @RequestParam("userId") Long userId,
			@RequestParam("ids") Long[] ids, @RequestParam("state") String state) {
		try {
			Set<Img> imgs = new HashSet<Img>();

			if (postingDTO.getId() != null) {
				Posting p = postingService.findById(postingDTO.getId());
				if (!p.getImgs().isEmpty()) {
					for (Img img : p.getImgs())
						imgs.add(img);
				}
			}
			for (Long id : ids) {
				Img img = imgService.findById(id);
				System.err.println(img.getId());
				imgs.add(img);
				System.err.println(imgs.size());
			}
			Posting posting = new Posting();

			PostingDTO.dtoToEntity(posting, postingDTO);
			posting.setImgs(imgs);
			posting.setCreateTime(new Date());
			User user = userService.findById(userId);
			posting.setAuthor(user);
			postingService.save(posting);
			if (state.equals("NO")) {
				posting.setState(LockedEmun.NO);
				postingService.save(posting);
				return new VueResponse(true, "保存成功！");
			} else {
				posting.setState(LockedEmun.YES);
				postingService.save(posting);
				return new VueResponse(true, "发表成功！");
			}

		} catch (Exception e) {
			// TODO: handle exception
			return new VueResponse(false, "发表失败！");
		}
	}

	@ApiOperation(value = "删除帖子", notes = "")
	@DeleteMapping
	public VueResponse delete(@RequestParam("id") Long id) {
		try {
			postingService.deleteById(id);
			return new VueResponse(true, "删除成功！");
		} catch (Exception e) {
			// TODO: handle exception
			return new VueResponse(true, "删除失败！");
		}
	}

	@ApiOperation(value = "关注帖子", notes = "")
	@PostMapping("/attention")
	public VueResponse attention(@RequestParam("postingId") Long postingId, @RequestParam("attention") String attention,
			HttpSession session) {
		try {

			User userSession = (User) session.getAttribute("userSession");
			Posting posting = postingService.findById(postingId);
			User user = userService.findById(userSession.getId());
			Set<Posting> attentions = new HashSet<Posting>();
			if (null != user.getAttentions()) {
				attentions.addAll(user.getAttentions());
			}
			if (attention.equals("YES")) {
				attentions.remove(posting);
				user.setAttentions(attentions);
				userService.save(user);
				return new VueResponse(true, "取消关注成功");

			} else {
				attentions.add(posting);
				user.setAttentions(attentions);
				userService.save(user);
				return new VueResponse(true, "关注成功");
			}

		} catch (Exception e) {
			// TODO: handle exception
			System.err.println(e);
			return new VueResponse(false, "关注失败");
		}
	}
}
